
package com.hlkj.pay.app.merchant.impl;

import static com.hlkj.pay.controller.BaseController.processQueryDate;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.fastjson.JSON;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.pojo.LocalContext;
import com.hlkj.framework.common.pojo.LocalRequest;
import com.hlkj.framework.common.pojo.PageResult;
import com.hlkj.framework.common.util.collection.CollectionUtils;
import com.hlkj.framework.common.util.id.IdUtils;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.executor.ExtensionExecutor;
import com.hlkj.framework.extension.scenario.BizScenario;
import com.hlkj.pay.app.merchant.IMerchantAccessAppService;
import com.hlkj.pay.app.merchant.IMerchantInfoAppService;
import com.hlkj.pay.app.merchant.ext.ChannelMerchantAccessExtPt;
import com.hlkj.pay.app.merchant.ext.MerchantExtConstant;
import com.hlkj.pay.app.merchant.ext.SystemMerchantAccessStatusExtPt;
import com.hlkj.pay.app.merchant.ext.dto.access.SystemMerchantAccessStatusContext;
import com.hlkj.pay.app.payment.IMerchantPaymentAppService;
import com.hlkj.pay.common.CommonResultCode;
import com.hlkj.pay.common.MerchantResultCode;
import com.hlkj.pay.common.OpenApiResultCode;
import com.hlkj.pay.common.PayResultCode;
import com.hlkj.pay.common.constants.MqConstant;
import com.hlkj.pay.config.ExtRocketMQTemplate;
import com.hlkj.pay.dto.LocalAdminUserRequest;
import com.hlkj.pay.dto.LocalMerchantRequest;
import com.hlkj.pay.dto.common.DefaultConfig;
import com.hlkj.pay.dto.merchant.*;
import com.hlkj.pay.dto.merchant.access.MerchantAccessAuthQueryDto;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.enums.PayEnums;
import com.hlkj.pay.gateway.merchant.IMerchantAccessGateway;
import com.hlkj.pay.gateway.order.IChannelPaymentGateway;
import com.hlkj.pay.infrastructure.model.merchant.*;
import com.hlkj.pay.infrastructure.model.pay.PayChannelDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderInfoDO;
import com.hlkj.pay.service.common.IBusinessLogService;
import com.hlkj.pay.service.common.IOperatedLogService;
import com.hlkj.pay.service.common.IPlatFormConfigService;
import com.hlkj.pay.service.merchant.IMerchantAccessAuthService;
import com.hlkj.pay.service.merchant.IMerchantAccessService;
import com.hlkj.pay.service.merchant.IMerchantApplicationService;
import com.hlkj.pay.service.merchant.IMerchantService;
import com.hlkj.pay.service.merchant.impl.MerchantHandler;
import com.hlkj.pay.service.pay.IPayChannelDictService;
import com.hlkj.pay.service.pay.IPayChannelService;
import com.hlkj.pay.service.pay.IPayWayService;
import com.hlkj.pay.service.pay.IProviderService;
import com.hlkj.pay.task.CommonTasks;
import com.hlkj.pay.util.MerchantUtils;
import com.hlkj.pay.vo.merchant.req.access.*;
import com.hlkj.pay.vo.merchant.req.payment.MerchantPaymentDetailReq;
import com.hlkj.pay.vo.merchant.resp.access.*;
import com.hlkj.pay.vo.merchant.resp.info.MerchantFeeConfigResp;
import com.hlkj.pay.vo.openapi.merchant.req.access.*;
import com.hlkj.pay.vo.order.req.MerchantAuthExportInfo;
import com.hlkj.pay.vo.order.req.MerchantChannelSplitReq;
import com.hlkj.pay.vo.order.req.MerchantProductReq;
import com.hlkj.pay.vo.order.req.MerchantTermAddReq;
import com.hlkj.pay.vo.order.resp.MerchantProductQueryResp;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.lang.WeightRandom;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.BeanUtil;
/**
 * @author HlpayTeam
 * @date 2024/09/25 13:09
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Validated
public class MerchantAccessAppServiceImpl implements IMerchantAccessAppService {

    private final IMerchantAccessService merchantAccessService;

    private final IOperatedLogService merchantAccessLogService;

    private final IMerchantService merchantService;

    private final IProviderService providerService;

    private final IPayChannelService payChannelService;

    private final IPayChannelDictService payChannelDictService;

    private final IMerchantApplicationService merchantApplicationService;

    private final ExtRocketMQTemplate extRocketMQTemplate;

    private final ExtensionExecutor extensionExecutor;

    private final MerchantHandler merchantHandler;

    private final IPlatFormConfigService platFormConfigService;

    private final MerchantAccessChannelService merchantAccessChannelService;

    private final IMerchantAccessGateway merchantAccessGateway;

    private final MerchantAccessStatusProcessHandler merchantAccessStatusProcessHandler;

    private final IMerchantPaymentAppService merchantPaymentAppService;

    private final IChannelPaymentGateway channelPaymentGateway;

    private final IBusinessLogService businessLogService;

    private final IMerchantAccessAuthService merchantAccessAuthService;

    private final IMerchantInfoAppService merchantInfoAppService;

    private final IPayWayService payWayService;

    private final CommonTasks commonTasks;

    @Value("${hlkj.pay.test:false}")
    private boolean payTest;

    @Override
    public CommonResult<Long> saveAccess(MerchantAccessReq merchantAccessReq) {
        log.info("saveAccess merchantAccessReq:{}", JsonUtils.toJsonString(merchantAccessReq));
        try {
            // CommonResult<Void> checkParams =
            // MerchantAccessParamsCheck.checkParams(merchantAccessReq);
            // if (!checkParams.isSuccess()) {
            // return CommonResult.error(checkParams.getCode(), checkParams.getMsg());
            // }
            MerchantEnum.ACCESS_STATUS status = MerchantEnum.ACCESS_STATUS.DRAFT;
            if(merchantAccessReq.getStatus() != null){
                status = merchantAccessReq.getStatus();
            }
            CommonResult<MerchantAccessDto> commonResult = processAccess(merchantAccessReq, status);
            if (!commonResult.isSuccess()) {
                return CommonResult.error(commonResult.getCode(), commonResult.getMsg());
            }
            return CommonResult.success(commonResult.getData().getMerchantAccessInfo().getId());
        }
        catch (Exception e) {
            log.error("saveAccess error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Long> submitAccess(@Valid MerchantAccessReq merchantAccessReq) {
        log.info("submitAccess merchantAccessReq:{}", JsonUtils.toJsonString(merchantAccessReq));
        try {
            CommonResult<Void> checkParams = MerchantAccessParamsCheck.checkParams(merchantAccessReq);
            if (!checkParams.isSuccess()) {
                return CommonResult.error(checkParams.getCode(), checkParams.getMsg());
            }
            CommonResult<MerchantAccessDto> commonResult = processAccess(merchantAccessReq, MerchantEnum.ACCESS_STATUS.SUBMIT);
            if (!commonResult.isSuccess()) {
                return CommonResult.error(commonResult.getCode(), commonResult.getMsg());
            }
            // 发送审核 mq
            MerchantAccessInfoDO merchantAccessInfo = commonResult.getData().getMerchantAccessInfo();
            Long id = merchantAccessInfo.getId();
            // sendMerchantAccessMessage(id);
            merchantAccessStatusProcessHandler.processAccess(id);
            return CommonResult.success(id);
        }
        catch (Exception e) {
            log.error("submitAccess error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<MerchantAccessDto> submitAccess(OpenApiMerchantAccessReq openApiMerchantAccessReq) {
        log.info("submitAccess openApiMerchantAccessReq:{}", JsonUtils.toJsonString(openApiMerchantAccessReq));
        try {
            CommonResult<Void> checkParams = MerchantAccessParamsCheck.checkParams(openApiMerchantAccessReq);
            if (!checkParams.isSuccess()) {
                return CommonResult.error(checkParams.getCode(), checkParams.getMsg());
            }
            CommonResult<MerchantAccessDto> commonResult = processAccess(openApiMerchantAccessReq);
            if (!commonResult.isSuccess()) {
                return CommonResult.error(commonResult.getCode(), commonResult.getMsg());
            }
            // 发送审核 mq
            MerchantAccessInfoDO merchantAccessInfo = commonResult.getData().getMerchantAccessInfo();
            Long id = merchantAccessInfo.getId();
            // sendMerchantAccessMessage(id);
            merchantAccessStatusProcessHandler.processAccess(id);
            return commonResult;
        }
        catch (Exception e) {
            log.error("submitAccess error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<MerchantAccessResp> merchantAccessInfo(Long id) {
        MerchantAccessDto merchantAccessDto = merchantAccessService.domainDetail(id);
        if (merchantAccessDto == null) {
            return CommonResult.success(null);
        }
        // 主表
        MerchantAccessInfoDO merchantAccessInfoDO = merchantAccessDto.getMerchantAccessInfo();
        MerchantAccessResp merchantAccess = BeanUtil.copy(merchantAccessInfoDO, MerchantAccessResp.class);
        MerchantAccessInfoResp merchantAccessInfo = BeanUtil.copy(merchantAccessInfoDO, MerchantAccessInfoResp.class);

        merchantAccess.setProviderName(providerService.queryByCode(merchantAccess.getProviderCode()).getName());
        merchantAccess.setChannelName(payChannelService.queryByCode(merchantAccess.getChannelCode()).getName());
        merchantAccess.setMerchantAccessInfo(merchantAccessInfo);

        // 进件营业执照信息
        MerchantAccessLicenseDO merchantAccessLicenseDO = merchantAccessDto.getMerchantAccessLicense();
        // 进件法人信息
        MerchantAccessCertInfoDO merchantAccessLegalDO = merchantAccessDto.getMerchantAccessLegal();
        // 联系人信息
        MerchantAccessCertInfoDO merchantAccessContactDO = merchantAccessDto.getMerchantAccessContact();
        // 实际控制人
        MerchantAccessCertInfoDO merchantAccessControllerDO = merchantAccessDto.getMerchantAccessController();
        // 进件受益人信息
        List<MerchantAccessCertInfoDO> merchantAccessBenefits = merchantAccessDto.getMerchantAccessBenefitList();
        // 企业控股股东信息
        List<MerchantAccessCertInfoDO> merchantAccessShareholdersList = merchantAccessDto.getMerchantAccessShareholderList();
        // 经营信息
        MerchantAccessBusinessDO merchantAccessBusinessDO = merchantAccessDto.getMerchantAccessBusiness();
        // 进件结算卡信息
        MerchantAccessCardDO merchantAccessCardDO = merchantAccessDto.getMerchantAccessCard();
        if (merchantAccessLegalDO != null) {
            MerchantAccessContactResp merchantAccessLegal = BeanUtil.copy(merchantAccessLegalDO, MerchantAccessContactResp.class);
            // dictValues.add(merchantAccessLegal.getCertType());
            merchantAccessLegal.setEmail(merchantAccessLegalDO.getOtherValue());
            merchantAccessInfo.setMerchantAccessLegal(merchantAccessLegal);

        }
        if (merchantAccessControllerDO != null) {
            MerchantAccessCertResp merchantAccessController = BeanUtil.copy(merchantAccessControllerDO, MerchantAccessCertResp.class);
            // dictValues.add(merchantAccessController.getCertType());
            merchantAccessInfo.setMerchantAccessController(merchantAccessController);
        }
        if (merchantAccessContactDO != null) {
            MerchantAccessContactResp merchantAccessContact = BeanUtil.copy(merchantAccessContactDO, MerchantAccessContactResp.class);
            merchantAccessContact.setEmail(merchantAccessContactDO.getOtherValue());
            // dictValues.add(merchantAccessContact.getCertType());
            merchantAccessInfo.setMerchantAccessContact(merchantAccessContact);
        }
        if (merchantAccessLicenseDO != null) {
            MerchantAccessLicenseResp merchantAccessLicense = BeanUtil.copy(merchantAccessLicenseDO, MerchantAccessLicenseResp.class);
            // dictValues.add(merchantAccessLicense.getCompanyType());
            if(StrUtil.isNotEmpty(merchantAccessLicenseDO.getRegisteredCapital())){
                merchantAccessLicense.setRegisteredCapital(new BigDecimal(merchantAccessLicenseDO.getRegisteredCapital()));
            }
            merchantAccessInfo.setMerchantAccessLicense(merchantAccessLicense);
        }
        if (!CollectionUtils.isEmpty(merchantAccessBenefits)) {
            List<MerchantAccessBenefitResp> benefitResps = new ArrayList<>();
            merchantAccessBenefits.stream().forEach(merchantAccessCertInfoDO -> {
                MerchantAccessBenefitResp benefitResp = BeanUtil.copy(merchantAccessCertInfoDO, MerchantAccessBenefitResp.class);
                benefitResp.setFinalBeneficiaryMode(merchantAccessCertInfoDO.getOtherValue());
                benefitResps.add(benefitResp);
            });
            merchantAccessInfo.setMerchantAccessBenefitList(benefitResps);
        }
        if (!CollectionUtils.isEmpty(merchantAccessShareholdersList)) {
            List<MerchantAccessCertResp> merchantAccessShareholders = BeanUtil.copy(merchantAccessShareholdersList, MerchantAccessCertResp.class);
            merchantAccessInfo.setMerchantAccessShareholderList(merchantAccessShareholders);
        }
        if (merchantAccessBusinessDO != null) {
            MerchantAccessBusinessResp accessBusiness = BeanUtil.copy(merchantAccessBusinessDO, MerchantAccessBusinessResp.class);
            accessBusiness.setMerchantAccessSceneList(merchantAccessBusinessDO.getSceneList());
            merchantAccess.setMerchantAccessBusiness(accessBusiness);

        }
        if (merchantAccessCardDO != null) {
            MerchantAccessCardResp merchantAccessCardResp = BeanUtil.copy(merchantAccessCardDO, MerchantAccessCardResp.class);
            merchantAccess.setMerchantAccessCard(merchantAccessCardResp);
        }
        return CommonResult.success(merchantAccess);
    }

    @Override
    public CommonResult<Void> platApprove(MerchantAccessApproveReq merchantAccessApproveReq) {
        log.info("platApprove merchantAccessApproveReq:{}", JsonUtils.toJsonString(merchantAccessApproveReq));
        try {
            Set<Long> ids = merchantAccessApproveReq.getIds();
            CommonEnum.YES_NO_TYPE yesNoType = CommonEnum.YES_NO_TYPE.from(merchantAccessApproveReq.getStatus());
            log.info("platApprove yesNoType:{}", yesNoType);
            for (Long id : ids) {
                MerchantAccessInfoDO merchantAccessInfoDO = merchantAccessService.detail(id);
                if (merchantAccessInfoDO == null) {
                    log.warn("merchantAccessApproveReq 数据不存在 id:{}", id);
                    return CommonResult.error(MerchantResultCode.MERCHANT_ACCESS_NOT_EXIST);
                }
                switch (yesNoType) {
                    case YES:
                        if (merchantAccessInfoDO.getStatus().equals(MerchantEnum.ACCESS_STATUS.CHANNEL_WAIT_APPROVE.getCode())) {
                            return CommonResult.success();
                        }
                }
                MerchantEnum.ACCESS_STATUS channelApprove;
                switch (yesNoType) {
                    case NO:
                        channelApprove = MerchantEnum.ACCESS_STATUS.APPROVE_REFUSE;
                        break;
                    default:
                        if (merchantAccessInfoDO.getLastStatus() == null || merchantAccessInfoDO.getLastStatus() <= MerchantEnum.ACCESS_STATUS.CHANNEL_APPROVE.getCode()) {
                            channelApprove = MerchantEnum.ACCESS_STATUS.CHANNEL_WAIT_APPROVE;
                        }
                        else {
                            channelApprove = MerchantEnum.ACCESS_STATUS.from(merchantAccessInfoDO.getLastStatus());
                        }
                }
                if (merchantAccessApproveReq.getRemark() == null) {
                    merchantAccessApproveReq.setRemark("");
                }
                log.info("platApprove channelApprove:{}", channelApprove);
                merchantAccessService.updateStatus(id, channelApprove, merchantAccessApproveReq.getRemark());
                switch (yesNoType) {
                    case YES:
                        MerchantAccessDto merchantAccessDto = merchantAccessService.domainDetail(id);
                        SystemMerchantAccessStatusContext systemMerchantAccessStatusContext = new SystemMerchantAccessStatusContext();
                        systemMerchantAccessStatusContext.setMerchantAccessDto(merchantAccessDto);
                        extensionExecutor.executeVoid(SystemMerchantAccessStatusExtPt.class,
                                BizScenario.valueOf(MerchantExtConstant.ACCESS_STATUS_SYSTEM_AUTH, merchantAccessDto.getMerchantAccessInfo().getChannelCode()),
                                ex -> ex.merchantAccessStatusProcess(systemMerchantAccessStatusContext));
                        // 发送消息进行下一个阶段的业务处理
                        // sendMerchantAccessMessage(id);
                        merchantAccessLogService.save(id, MerchantEnum.MERCHANT_LOG_TYPE.ACCESS, "平台审核成功", "进件审核成功");
                        merchantAccessStatusProcessHandler.processAccess(id);
                        break;
                    default:
                        merchantAccessLogService.save(id, MerchantEnum.MERCHANT_LOG_TYPE.ACCESS, "平台驳回", merchantAccessApproveReq.getRemark());
                }
            }
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("submitAccess error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> accessChannel(MerchantAccessChannelReq merchantAccessChannelReq) {
        log.info("accessChannel merchantAccessChannelReq:{}", JsonUtils.toJsonString(merchantAccessChannelReq));
        try {
            MerchantAccessInfoDO merchantAccessInfoDO = merchantAccessService.detail(merchantAccessChannelReq.getId());
            if (merchantAccessInfoDO == null) {
                return CommonResult.error(MerchantResultCode.MERCHANT_ACCESS_NOT_EXIST);
            }
            MerchantAppQueryDto merchantInfoQueryDO = new MerchantAppQueryDto();
            merchantInfoQueryDO.setSn(merchantAccessInfoDO.getSn());
            List<String> appidList = new ArrayList<>();
            appidList.add(merchantAccessChannelReq.getAppIds());
            merchantInfoQueryDO.setAppIds(appidList);
            List<MerchantAppDO> merchantAppList = merchantApplicationService.queryList(merchantInfoQueryDO);
            // 比较请求的appis 是否在该商户下
            if (CollectionUtils.isEmpty(merchantAppList)) {
                return CommonResult.error(MerchantResultCode.MERCHANT_APP_NOT_EXIST);
            }

            //判断是否分配对应通道，如果已分配 返回
            MerchantAppChannelDO merchantAppChannel = merchantApplicationService.queryDetailByAccessId(merchantAccessChannelReq.getAppIds(), merchantAccessChannelReq.getId());
            if (!Objects.isNull(merchantAppChannel)) {
                return CommonResult.error(MerchantResultCode.MERCHANT_APP_CHANNEL_EXIST);
            }

            AccessChannelParamsDto accessChannelParamsDto = new AccessChannelParamsDto();
            accessChannelParamsDto.setSubMchId(merchantAccessInfoDO.getSubMchId());
            accessChannelParamsDto.setExtendA(merchantAccessInfoDO.getExtendA());
            accessChannelParamsDto.setExtendB(merchantAccessInfoDO.getExtendB());
            // 获取通道参数
            String channelParams = extensionExecutor.execute(ChannelMerchantAccessExtPt.class, BizScenario.valueOf(merchantAccessInfoDO.getChannelCode()),
                    ex -> ex.channelParams(accessChannelParamsDto));
            Snowflake snowflake = IdUtils.getSnowflake();
            List<MerchantAppChannelDO> merchantAppChannelList = new ArrayList<>();
            merchantAppList.stream().forEach(merchantAppDO -> {
                MerchantAppChannelDO merchantAppChannelDO = new MerchantAppChannelDO();
                merchantAppChannelDO.setCode(snowflake.nextIdStr());
                merchantAppChannelDO.setType(MerchantEnum.APP_CHANNEL_TYPE.MERCHANT_SPECIAL.getCode());
                merchantAppChannelDO.setSn(merchantAppDO.getSn());
                merchantAppChannelDO.setAppId(merchantAppDO.getAppId());
                merchantAppChannelDO.setProviderCode(merchantAccessInfoDO.getProviderCode());
                merchantAppChannelDO.setChannelCode(merchantAccessInfoDO.getChannelCode());
                merchantAppChannelDO.setAppConfigJson(channelParams);
                merchantAppChannelDO.setStatus(CommonEnum.YES_NO_TYPE.NO.getCode());
                merchantAppChannelDO.setWeight(1);
                merchantAppChannelDO.setSubMchId(merchantAccessInfoDO.getSubMchId());
                merchantAppChannelDO.setPayWayCode(getPayWaycodes(merchantAccessInfoDO.getSn(), merchantAccessInfoDO.getChannelCode()));
                // merchantAppChannelDO.setRemark();
                merchantAppChannelDO.setAccessId(merchantAccessInfoDO.getId());
                merchantAppChannelList.add(merchantAppChannelDO);
            });
            merchantApplicationService.saveBatchMerchantAppChannel(merchantAppChannelList);
        }
        catch (Exception e) {
            log.error("accessChannel error:{}", e.getMessage(), e);
        }
        return CommonResult.success();
    }

    @Override
    public CommonResult<Void> delete(Long id) {
        log.info("delete id:{}", id);
        try {
            if (id == null) {
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
            }
            MerchantAccessInfoDO merchantAccessInfoDO = merchantAccessService.detail(id);
            if (merchantAccessInfoDO == null) {
                log.warn("delete 数据不存在 id:{}", id);
                return CommonResult.error(MerchantResultCode.MERCHANT_ACCESS_NOT_EXIST);
            }
            merchantAccessService.delete(id);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("submitAccess error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<MerchantAccessAuthResp> queryMerchantAccessAuth(Long id) {
        MerchantAccessDto merchantAccessDto = merchantAccessService.domainDetail(id);
        if (merchantAccessDto == null) {
            return CommonResult.error(MerchantResultCode.MERCHANT_ACCESS_NOT_EXIST);
        }
        MerchantAccessAuthResp merchantAccessAuthResp = new MerchantAccessAuthResp();
        MerchantAccessInfoDO merchantAccessInfo = merchantAccessDto.getMerchantAccessInfo();
        merchantAccessAuthResp.setMerchantAccessInfo(merchantAccessInfo);
        if ("alipayFund".equals(merchantAccessInfo.getChannelCode())) {
            MerchantAppChannelDO merchantAppChannelDO = merchantApplicationService.queryDetailByAccessId(merchantAccessInfo.getId(), MerchantEnum.DATA_RELATION_TYPE.ACCESS);
            List<MerchantAcctBalanceDto> merchantAcctBalanceDtos = channelPaymentGateway.queryChannelPaymentAccount(merchantAppChannelDO.getCode(), new ArrayList<>());
            if (CollectionUtils.isNotEmpty(merchantAcctBalanceDtos)) {
                merchantAccessAuthResp.setMerchantAcctBalanceDto(merchantAcctBalanceDtos.get(0));
            }
        }
        else {
            PayEnums.COMMON_DICT_KEY commonDictKey = PayEnums.COMMON_DICT_KEY.from(merchantAccessInfo.getChannelCode());
            List<MerchantAccessAuthDO> merchantAccessAuthDbList = merchantAccessAuthService.queryMerchantAccessAuth(id);
            // 判断认证信息是否需要重新加载
            if (commonDictKey != null && commonDictKey.isReloadAuth()) {
                log.info("通道编号 channelCode(:{},需要重新加载认证信息", merchantAccessInfo.getChannelCode());
                //加入授权信息， 暂时新生使用
                merchantAccessDto.setMerchantAccessAuthList(merchantAccessAuthDbList);
                merchantAccessChannelService.reloadMerchantAuth(merchantAccessDto);
            }
            List<MerchantAccessAuthDO> merchantAccessAuthResult = new ArrayList<>();
            List<MerchantAccessAuthDO> wechatAccessAuthDbList = null;
            List<MerchantAccessAuthDO> aliAccessAuthDbList = null;
            if (!CollectionUtils.isEmpty(merchantAccessAuthDbList)) {
                wechatAccessAuthDbList = merchantAccessAuthDbList.stream().filter(merchantAccessAuthDO -> PayEnums.PAY_TYPE.WECHAT.getCode().equals(merchantAccessAuthDO.getType()))
                        .collect(Collectors.toList());
                aliAccessAuthDbList = merchantAccessAuthDbList.stream().filter(merchantAccessAuthDO -> PayEnums.PAY_TYPE.ALIPAY.getCode().equals(merchantAccessAuthDO.getType()))
                        .collect(Collectors.toList());
            }
            // 首先获取微信支付配置
            MerchantWechatConfigListDto merchantWechatConfigListDto = merchantAccessChannelService.wechatConfigQuery(merchantAccessDto, false, wechatAccessAuthDbList);
            merchantAccessAuthResp.setWechatConfig(merchantWechatConfigListDto);
            ProviderChannelConfigDO providerChannelConfigDO = providerService.queryConfig(merchantAccessInfo.getProviderCode(), merchantAccessInfo.getChannelCode());
            // 微信认证
            List<MerchantAccessAuthDO> wechatAccessAuthList = merchantAccessChannelService.wechatAuthConfigQuery(merchantAccessDto, false, wechatAccessAuthDbList);
            processAuthList(merchantAccessAuthResult, wechatAccessAuthList, wechatAccessAuthDbList, providerChannelConfigDO);
            // 支付宝认证
            List<MerchantAccessAuthDO> aliAccessAuthList = merchantAccessChannelService.aliAuthConfigQuery(merchantAccessDto, false, aliAccessAuthDbList);
            processAuthList(merchantAccessAuthResult, aliAccessAuthList, aliAccessAuthDbList, providerChannelConfigDO);
            List<MerchantAccessAuthDetailResp> accessAuthDetailResps = BeanUtil.copy(merchantAccessAuthResult, MerchantAccessAuthDetailResp.class);
            merchantAccessAuthResp.setAuthList(accessAuthDetailResps);
        }
        MerchantAppChannelDO merchantAppChannelDO = merchantApplicationService.queryDetailByAccessId(id, MerchantEnum.DATA_RELATION_TYPE.ACCESS);
        if (merchantAppChannelDO != null) {
            merchantAccessAuthResp.setMchChannelCode(merchantAppChannelDO.getCode());
        }
        return CommonResult.success(merchantAccessAuthResp);
    }

    void  processAuthList(List<MerchantAccessAuthDO> merchantAccessAuthResult, List<MerchantAccessAuthDO> accessAuthList, List<MerchantAccessAuthDO> accessAuthDbList,
            ProviderChannelConfigDO providerChannelConfigDO) {
        if (CollectionUtils.isEmpty(accessAuthList)) {
            return;
        }
        merchantAccessAuthService.saveMerchantAccessAuth(accessAuthList, accessAuthDbList);
        String paramsConfig = providerChannelConfigDO.getParamsConfig();
        Map<String, Object> paramsMap = JsonUtils.parseObject(paramsConfig, Map.class);
        accessAuthList.stream().forEach(accessAuth -> {
            PayEnums.PAY_TYPE payType = PayEnums.PAY_TYPE.fromByCode(accessAuth.getType());
            if (!StringUtils.hasText(accessAuth.getAuthUrl())) {
                switch (payType) {
                    case WECHAT:
                        Object object = paramsMap.get("wxQrcode");
                        if (object != null) {
                            accessAuth.setAuthUrl(object.toString());
                        }
                        break;
                    case ALIPAY:
                        object = paramsMap.get("aliQrcode");
                        if (object != null) {
                            accessAuth.setAuthUrl(object.toString());
                        }
                        break;
                }
            }
        });
        merchantAccessAuthResult.addAll(accessAuthList);
    }

    @Override
    public CommonResult<Void> submitWechatConfig(MerchantWechatConfigDto merchantAccessChannelReq) {
        if (!StringUtils.hasText(merchantAccessChannelReq.getAppId()) && !StringUtils.hasText(merchantAccessChannelReq.getJsAPIPath())) {
            return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
        }
        MerchantAccessAuthDO merchantAccessAuthDO = merchantAccessAuthService.queryMerchantAccessAuthById(merchantAccessChannelReq.getId());
        if (merchantAccessAuthDO == null) {
            return CommonResult.error(MerchantResultCode.MERCHANT_ACCESS_NOT_EXIST);
        }
        MerchantAccessDto merchantAccessDto = merchantAccessService.domainDetail(merchantAccessAuthDO.getAccessId());
        if (merchantAccessDto == null) {
            return CommonResult.error(MerchantResultCode.MERCHANT_ACCESS_NOT_EXIST);
        }
        return merchantAccessGateway.wechatConfigAdd(merchantAccessDto, merchantAccessAuthDO, merchantAccessChannelReq);
    }

    @Override
    public CommonResult<String> fuiouTermAdd(@Valid MerchantTermAddReq merchantTermAddReq) {
        MerchantAppChannelDO merchantAppChannelDO = merchantApplicationService.queryAppChannelDetail(merchantTermAddReq.getMchChannelCode());
        if (merchantAppChannelDO == null) {
            return CommonResult.error(OpenApiResultCode.MERCHANT_APP_NOT_EXIST);
        }
        // if
        // (CommonEnum.YES_NO_TYPE.NO.getCode().equals(merchantAppChannelDO.getStatus()))
        // {
        // return CommonResult.error(OpenApiResultCode.MERCHANT_APP_NOT_EFFECT);
        // }
        if (!MerchantExtConstant.CHANNEL_FU_YOU.equals(merchantAppChannelDO.getChannelCode())) {
            return CommonResult.error(OpenApiResultCode.MERCHANT_TERM_NOT_SUPPORT);
        }
        MerchantAccessDto merchantAccessDto = merchantAccessService.domainDetail(merchantAppChannelDO.getAccessId());
        CommonResult<String> commonResult = merchantAccessGateway.termAdd(merchantAccessDto, merchantAppChannelDO, merchantTermAddReq);
        if (!commonResult.isSuccess()) {
            return CommonResult.error(OpenApiResultCode.MERCHANT_TERM_NOT_ERROR.getCode(), commonResult.getMsg());
        }
        return CommonResult.success(commonResult.getData());
    }

    @Override
    public CommonResult<String> merchantAccessRecharge(MerchantAccessRechargeReq merchantAccessRechargeReq) {
        MerchantPaymentDetailReq merchantPaymentDetailReq = new MerchantPaymentDetailReq();
        MerchantAppChannelDO merchantAppChannelDO = merchantApplicationService.queryDetailByAccessId(merchantAccessRechargeReq.getId(), MerchantEnum.DATA_RELATION_TYPE.ACCESS);
        merchantPaymentDetailReq.setMchChannelCode(merchantAppChannelDO.getCode());
        merchantPaymentDetailReq.setPayAmount(MerchantUtils.stringToBigDecimal(merchantAccessRechargeReq.getAmount()));
        merchantPaymentDetailReq.setRemark(merchantAccessRechargeReq.getRemark());
        merchantPaymentDetailReq.setPaymentType(CommonEnum.YES_NO_TYPE.NO.getCode());
        return merchantPaymentAppService.addRecharge(merchantPaymentDetailReq);
    }

    @Override
    public CommonResult<MerchantAccessDto> accessDetail(OpenApiMerchantAccessQueryReq accessQueryReq) {
        log.info("accessDetail accessQueryReq:{}", JsonUtils.toJsonString(accessQueryReq));
        try {
            if (!StringUtils.hasText(accessQueryReq.getMchOrderNo()) && !StringUtils.hasText(accessQueryReq.getRequestId())) {
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
            }
            MerchantAccessInfoDO merchantAccessInfoDO = null;
            if (StringUtils.hasText(accessQueryReq.getMchOrderNo())) {
                merchantAccessInfoDO = merchantAccessService.queryByMchOrderNo(LocalContext.get().getSn(), accessQueryReq.getMchOrderNo());
                if (merchantAccessInfoDO == null) {
                    return CommonResult.error(OpenApiResultCode.DATA_NOT_EXIST);
                }
            }
            else if (StringUtils.hasText(accessQueryReq.getRequestId())) {
                merchantAccessInfoDO = merchantAccessService.queryByRequestId(accessQueryReq.getRequestId());
                if (merchantAccessInfoDO == null) {
                    return CommonResult.error(OpenApiResultCode.DATA_NOT_EXIST);
                }
            }
            MerchantAccessDto merchantAccessDto = merchantAccessService.domainDetail(merchantAccessInfoDO.getId());
            return CommonResult.success(merchantAccessDto);
        }
        catch (Exception e) {
            log.error("submitAccess error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<MerchantChannelSplitReq> easySplit(MerchantChannelSplitReq merchantChannelSplitReq) {
        MerchantAppChannelDO merchantAppChannelDO = merchantApplicationService.queryAppChannelDetail(merchantChannelSplitReq.getMchChannelCode());
        if (merchantAppChannelDO == null) {
            return CommonResult.error(MerchantResultCode.MERCHANT_APP_NOT_EXIST);
        }
        MerchantAccessDto merchantAccessDto = merchantAccessService.domainDetail(merchantAppChannelDO.getAccessId());
        // 不判断通道状态
//        if (CommonEnum.YES_NO_TYPE.NO.getCode().equals(merchantAppChannelDO.getStatus())) {
//            return CommonResult.error(OpenApiResultCode.MERCHANT_APP_CHANNEL_NOT_EFFECT);
//        }
//         if (!MerchantExtConstant.CHANNEL_EASY_PAY.equals(merchantAppChannelDO.getChannelCode())) {
//             return CommonResult.error(OpenApiResultCode.MERCHANT_APP_CHANNEL_NOT_EXIST);
//         }
        // 一次
        if(merchantChannelSplitReq.getNum() == null || merchantChannelSplitReq.getNum() == 0 || merchantChannelSplitReq.getNum() == 1){
            CommonResult<MerchantAccessAuthDO> commonResult = merchantAccessGateway.easySplit(merchantAccessDto, merchantAppChannelDO, merchantChannelSplitReq);
            MerchantAccessAuthDO accessAuthDO = commonResult.getData();
            if (accessAuthDO != null) {
                merchantAccessAuthService.saveMerchantAccessAuth(accessAuthDO);
            }
            if (!commonResult.isSuccess()) {
                return CommonResult.error(OpenApiResultCode.MERCHANT_CHANNEL_SPLIT_ERROR.getCode(), commonResult.getMsg());
            }
        }else{
            // 异步拆分
            commonTasks.easySplit(merchantChannelSplitReq);
        }
        return CommonResult.success(merchantChannelSplitReq);
    }

    @Override
    public CommonResult<Void> importExcel(Long accessId, MultipartFile excel) {

        if(accessId == null){
            return CommonResult.error(MerchantResultCode.MERCHANT_ACCESS_NOT_EXIST);
        }
        MerchantAccessInfoDO merchantAccessInfoDO = merchantAccessService.detail(accessId);
        if(merchantAccessInfoDO == null){
            return CommonResult.error(MerchantResultCode.MERCHANT_ACCESS_NOT_EXIST);
        }
        if(excel == null){
            return CommonResult.success();
        }
        try{
            // 具体需要返回多少行可以在`PageReadListener`的构造函数设置
            EasyExcel.read(excel.getInputStream(), MerchantAuthExportInfo.class, new PageReadListener<MerchantAuthExportInfo>(dataList -> {
                if(CollUtil.isNotEmpty(dataList)){
                    List<MerchantAccessAuthDO> authDOList = new ArrayList<>();
                    for(MerchantAuthExportInfo exportInfo:dataList){
                        if(StrUtil.isNotEmpty(exportInfo.getSubMchId()) && exportInfo.getType() != null){
                            // 支付宝或微信类型
                            if(exportInfo.getType() == 1 || exportInfo.getType() == 2){
                                MerchantAccessAuthDO authDO = BeanUtil.copy(exportInfo,MerchantAccessAuthDO.class);
                                authDOList.add(authDO);
                            }
                        }
                    }
                    log.info("读取importExcel数据:{}", JSON.toJSONString(dataList));
                    // List<MerchantAccessAuthDO> authDOList = JSONUtil.toList(JSONUtil.toJsonStr(dataList),MerchantAccessAuthDO.class);

                    for(MerchantAccessAuthDO authDO:authDOList){
                        authDO.setAccessId(accessId);
                        authDO.setStatus(MerchantEnum.MERCHANT_AUTH_STATUS.APPROVE.getCode());
                        authDO.setAuthStatus(1);
                        authDO.setState(1);
                        authDO.setLimitRouter(1);
                        authDO.setSerialCode(authDO.getSubMchId());
                        authDO.setSn(merchantAccessInfoDO.getSn());
                    }
                    merchantAccessAuthService.addMerchantAccessAuth(authDOList);
                }

            })).sheet().doRead();
        }catch (Exception e){
            log.error("importExcel error:{}",  e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
        return  CommonResult.success();
    }

    /**
     * 进件保存处理
     *
     * @param merchantAccessReq
     * @param accessStatus
     * @return
     */
    CommonResult<MerchantAccessDto> processAccess(MerchantAccessReq merchantAccessReq, MerchantEnum.ACCESS_STATUS accessStatus) {
        MerchantAccessInfoReq merchantAccessInfo = merchantAccessReq.getMerchantAccessInfo();
        // 联系人同法人
        if (CommonEnum.YES_NO_TYPE.YES.getCode().equals(merchantAccessInfo.getContactType())) {
            merchantAccessInfo.setMerchantAccessContact(merchantAccessInfo.getMerchantAccessLegal());
        }
        // 控制人同法人
        if (CommonEnum.YES_NO_TYPE.YES.getCode().equals(merchantAccessInfo.getControllerType())) {
            merchantAccessInfo.setMerchantAccessController(merchantAccessInfo.getMerchantAccessLegal());
        }
        // 商户后台不传sn
        LocalRequest localRequest = LocalContext.get();
        if (!StringUtils.hasText(merchantAccessReq.getSn())) {
            LocalAdminUserRequest localAdminUserRequest = (LocalAdminUserRequest) localRequest;
            if (localAdminUserRequest != null) {
                // 运营后台 querySn没有值
                merchantAccessReq.setSn(localAdminUserRequest.getQuerySn());
            }
        }
        if (!StringUtils.hasText(merchantAccessReq.getSn())) {
            // 获取联系人信息
            MerchantAccessContactReq merchantAccessContact = merchantAccessReq.getMerchantAccessInfo().getMerchantAccessContact();
            String account = merchantAccessContact.getPhone();
            MerchantInfoDO merchantInfoDO = merchantService.queryMerchantByAccount(account);
            if (merchantInfoDO != null) {
                return CommonResult.error(MerchantResultCode.MERCHANT_DOES_EXIST);
            }
            MerchantInfoRegisterDto merchantInfoRegisterDto = new MerchantInfoRegisterDto();
            merchantInfoRegisterDto.setPhone(merchantAccessContact.getPhone());
            merchantInfoRegisterDto.setAccount(account);
            // merchantInfoRegisterDto.setName(merchantInfoDO.getName());
            merchantInfoRegisterDto.setSysType(CommonEnum.SYS_TYPE.MERCHANT);
            merchantInfoRegisterDto.setCheckAgreement(CommonEnum.YES_NO_TYPE.NO.getCode());
            merchantInfoRegisterDto.setSnType(MerchantEnum.MERCHANT_SN_TYPE.MERCHANT.getCode());
            CommonResult<String> register = merchantHandler.register(merchantInfoRegisterDto, Arrays.asList(merchantAccessReq.getProviderCode()),
                    Arrays.asList(merchantAccessReq.getChannelCode()));
            merchantAccessReq.setSn(register.getData());
            log.info("注册后的sn为:{}", merchantAccessReq.getSn());
        }
        // 默认通道 默认服务商
        if (!StringUtils.hasText(merchantAccessReq.getProviderCode()) || !StringUtils.hasText(merchantAccessReq.getChannelCode())) {
            DefaultConfig defaultConfig = platFormConfigService.getDefaultConfig();
            DefaultConfig.OtherConfig otherConfig = defaultConfig.getOtherConfig();
            if (!StringUtils.hasText(merchantAccessReq.getProviderCode()) && !CollectionUtils.isEmpty(otherConfig.getProviderCodeList())) {
                merchantAccessReq.setProviderCode(otherConfig.getProviderCodeList().get(0));
            }
            if (!StringUtils.hasText(merchantAccessReq.getChannelCode()) && !CollectionUtils.isEmpty(otherConfig.getChannelCodeList())) {
                merchantAccessReq.setChannelCode(otherConfig.getChannelCodeList().get(0));
            }
        }
        if (!StringUtils.hasText(merchantAccessReq.getProviderCode()) || !StringUtils.hasText(merchantAccessReq.getChannelCode())) {
            return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
        }
        MerchantInfoDO merchantInfoDO = merchantService.queryMerchant(merchantAccessReq.getSn());
        if (merchantInfoDO == null) {
            return CommonResult.error(MerchantResultCode.MERCHANT_NOT_EXIST);
        }
        ProviderInfoDO providerInfoDO = providerService.queryByCode(merchantAccessReq.getProviderCode());
        if (providerInfoDO == null) {
            return CommonResult.error(PayResultCode.PROVIDER_NOT_EXITS);
        }
        PayChannelDO payChannelDO = payChannelService.queryByCode(merchantAccessReq.getChannelCode());
        if (payChannelDO == null) {
            return CommonResult.error(PayResultCode.PAY_CHANNEL_NOT_EXITS);
        }
        MerchantAccessDto merchantAccessDto = new MerchantAccessDto();

        MerchantAccessBusinessReq merchantAccessBusiness = merchantAccessReq.getMerchantAccessBusiness();
        // 进件主表信息
        MerchantAccessInfoDO merchantAccessInfoDO = new MerchantAccessInfoDO();
        merchantAccessInfoDO.setSn(merchantAccessReq.getSn());
        merchantAccessInfoDO.setProviderCode(merchantAccessReq.getProviderCode());
        merchantAccessInfoDO.setChannelCode(merchantAccessReq.getChannelCode());
        merchantAccessInfoDO.setSn(merchantAccessReq.getSn());
        merchantAccessInfoDO.setId(merchantAccessReq.getId());
        merchantAccessInfoDO.setControllerType(merchantAccessInfo.getControllerType());
        merchantAccessInfoDO.setContactType(merchantAccessInfo.getContactType());
        merchantAccessInfoDO.setType(merchantAccessInfo.getType());
        merchantAccessInfoDO.setRemark("");
        merchantAccessInfoDO.setMerchantAccessType(CommonEnum.YES_NO_TYPE.NO.getCode());
        if (merchantAccessReq.getSourceFrom() != null)
            merchantAccessInfoDO.setSourceFrom(merchantAccessReq.getSourceFrom());
        merchantAccessDto.setMerchantAccessInfo(merchantAccessInfoDO);
        // 进件营业执照信息
        MerchantAccessLicenseReq merchantAccessLicense = merchantAccessInfo.getMerchantAccessLicense();
        // 进件法人信息
        MerchantAccessCertInfoDO merchantAccessLegalDO = BeanUtil.copy(merchantAccessInfo.getMerchantAccessLegal(), MerchantAccessCertInfoDO.class);
        merchantAccessLegalDO.setOtherValue(merchantAccessInfo.getMerchantAccessLegal().getEmail());
        if (merchantAccessLicense != null) {
            MerchantAccessLicenseDO merchantAccessLicenseDO = BeanUtil.copy(merchantAccessLicense, MerchantAccessLicenseDO.class);
            merchantAccessDto.setMerchantAccessLicense(merchantAccessLicenseDO);
            merchantAccessInfoDO.setName(merchantAccessLicenseDO.getName());
        }
        else {
            merchantAccessInfoDO.setName(merchantAccessLegalDO.getName());
        }
        merchantAccessInfoDO.setShortName(merchantAccessBusiness.getShortName());
        merchantAccessDto.setMerchantAccessLegal(merchantAccessLegalDO);

        // 联系人信息
        MerchantAccessCertInfoDO merchantAccessContactDO = BeanUtil.copy(merchantAccessInfo.getMerchantAccessContact(), MerchantAccessCertInfoDO.class);
        merchantAccessContactDO.setOtherValue(merchantAccessInfo.getMerchantAccessContact().getEmail());
        merchantAccessDto.setMerchantAccessContact(merchantAccessContactDO);

        // 实际控制人
        MerchantAccessCertReq merchantAccessController = merchantAccessInfo.getMerchantAccessController();
        if (merchantAccessController != null) {
            MerchantAccessCertInfoDO merchantAccessControllerDO = BeanUtil.copy(merchantAccessInfo.getMerchantAccessController(), MerchantAccessCertInfoDO.class);
            merchantAccessDto.setMerchantAccessController(merchantAccessControllerDO);
        }
        // 进件受益人信息
        List<MerchantAccessBenefitReq> merchantAccessBenefitList = merchantAccessInfo.getMerchantAccessBenefitList();
        if (!CollectionUtils.isEmpty(merchantAccessBenefitList)) {
            List<MerchantAccessCertInfoDO> merchantAccessBenefits = new ArrayList<>();
            merchantAccessBenefitList.stream().forEach(merchantAccessBenefitReq -> {
                MerchantAccessCertInfoDO merchantAccessCertInfoDO = BeanUtil.copy(merchantAccessBenefitReq, MerchantAccessCertInfoDO.class);
                merchantAccessCertInfoDO.setOtherValue(merchantAccessBenefitReq.getFinalBeneficiaryMode());
                merchantAccessBenefits.add(merchantAccessCertInfoDO);
            });
            merchantAccessDto.setMerchantAccessBenefitList(merchantAccessBenefits);
        }
        // 企业控股股东信息
        List<MerchantAccessCertReq> merchantAccessShareholderList = merchantAccessInfo.getMerchantAccessShareholderList();
        if (!CollectionUtils.isEmpty(merchantAccessBenefitList)) {
            List<MerchantAccessCertInfoDO> merchantAccessShareholders = BeanUtil.copy(merchantAccessShareholderList, MerchantAccessCertInfoDO.class);
            merchantAccessDto.setMerchantAccessShareholderList(merchantAccessShareholders);
        }
        // 经营信息
        MerchantAccessBusinessDO merchantAccessBusinessDO = BeanUtil.copy(merchantAccessBusiness, MerchantAccessBusinessDO.class);
        if (CollectionUtils.isNotEmpty(merchantAccessBusiness.getFileUrls())) {
            merchantAccessBusinessDO.setFileUrlJson(JsonUtils.toJsonString(merchantAccessBusiness.getFileUrls()));
        }
        if (CollectionUtils.isNotEmpty(merchantAccessBusiness.getBusinessLicenses())) {
            merchantAccessBusinessDO.setLicenseJson(JsonUtils.toJsonString(merchantAccessBusiness.getBusinessLicenses()));
        }

        if (!StringUtils.hasText(merchantAccessBusiness.getAlipayMcc())) {
            merchantAccessBusinessDO.setAlipayMcc("");
        }
        if (!StringUtils.hasText(merchantAccessBusiness.getWechatMcc())) {
            merchantAccessBusinessDO.setWechatMcc("");
        }

        // 进件场景信息
        List<MerchantAccessScene> merchantAccessSceneList = merchantAccessBusiness.getMerchantAccessSceneList();
        if (!CollectionUtils.isEmpty(merchantAccessSceneList)) {
            merchantAccessBusinessDO.setSceneJson(JsonUtils.toJsonString(merchantAccessSceneList));
        }
        // 进件结算卡信息
        MerchantAccessCardDO merchantAccessCardDO = BeanUtil.copy(merchantAccessReq.getMerchantAccessCard(), MerchantAccessCardDO.class);
        merchantAccessDto.setMerchantAccessBusiness(merchantAccessBusinessDO);
        merchantAccessDto.setMerchantAccessCard(merchantAccessCardDO);
        // if (!StringUtils.hasText(merchantAccessBusinessDO.getName())) {
        // merchantAccessBusinessDO.setName(merchantInfoDO.getName());
        // }
        merchantAccessInfoDO.setSnType(merchantInfoDO.getSnType());
        merchantAccessInfoDO.setSysType(localRequest.getSysType());
        merchantAccessInfoDO.setStatus(accessStatus.getCode());
        merchantAccessInfoDO.setRemark("");
        // 易生修改时直接走重新进件
        if (merchantAccessInfoDO.getChannelCode().equals(MerchantExtConstant.CHANNEL_EASY_PAY)) {
            merchantAccessInfoDO.setLastStatus(accessStatus.getCode());
            merchantAccessInfoDO.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.SUBMIT.getCode());
        }
        if (merchantAccessReq.getId() == null) {
            merchantAccessInfoDO = merchantAccessDto.getMerchantAccessInfo();
            merchantAccessInfoDO.setRequestId(IdUtils.getSnowflakeNextIdStr());
            merchantAccessInfoDO.setMerchantChannelId(IdUtils.getSnowflakeNextIdStr());
            merchantAccessService.saveAccess(merchantAccessDto);
            merchantAccessLogService.save(merchantAccessDto.getMerchantAccessInfo().getId(), MerchantEnum.MERCHANT_LOG_TYPE.ACCESS, "添加进件资料",
                    "新增进件");
        }
        else {
            // 恢复到上一个状态
            MerchantAccessInfoDO detail = merchantAccessService.detail(merchantAccessReq.getId());
            if (detail.getLastStatus() != null && detail.getLastStatus() > MerchantEnum.ACCESS_STATUS.CHANNEL_APPROVE.getCode()) {
                merchantAccessInfoDO.setStatus(detail.getLastStatus());
            }
            merchantAccessService.updateAccess(merchantAccessDto);
            merchantAccessLogService.save(merchantAccessDto.getMerchantAccessInfo().getId(), MerchantEnum.MERCHANT_LOG_TYPE.ACCESS, "修改进件资料",
                    "修改进件");
        }
        return CommonResult.success(merchantAccessDto);
    }

    /**
     * openaAPi 进件
     *
     * @param merchantAccessReq
     * @return
     */
    CommonResult<MerchantAccessDto> processAccess(OpenApiMerchantAccessReq merchantAccessReq) {
        LocalMerchantRequest localRequest = (LocalMerchantRequest) LocalContext.get();
        MerchantAccessInfoDO accessInfoDO = merchantAccessService.queryByMchOrderNo(localRequest.getSn(), merchantAccessReq.getMchOrderNo());
        if (accessInfoDO != null && !MerchantEnum.ACCESS_STATUS.APPROVE_REFUSE.getCode().equals(accessInfoDO.getStatus())) {
            return CommonResult.error(OpenApiResultCode.MERCHANT_ACCESS_EXIST);
        }
        OpenApiMerchantAccessInfoReq merchantAccessInfo = merchantAccessReq.getMerchantAccessInfo();
        // 联系人同法人
        if (CommonEnum.YES_NO_TYPE.YES.getCode().equals(merchantAccessInfo.getContactType())) {
            merchantAccessInfo.setMerchantAccessContact(merchantAccessInfo.getMerchantAccessLegal());
        }
        // 控制人同法人
        if (CommonEnum.YES_NO_TYPE.YES.getCode().equals(merchantAccessInfo.getControllerType())) {
            merchantAccessInfo.setMerchantAccessController(merchantAccessInfo.getMerchantAccessLegal());
        }
        if (!StringUtils.hasText(merchantAccessReq.getProviderCode()) || !StringUtils.hasText(merchantAccessReq.getChannelCode())) {
            return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
        }
        MerchantInfoDO merchantInfoDO = merchantService.queryMerchant(localRequest.getSn());
        // if (merchantInfoDO == null) {
        // return CommonResult.error(MerchantResultCode.MERCHANT_NOT_EXIST);
        // }
        ProviderInfoDO providerInfoDO = providerService.queryByCode(merchantAccessReq.getProviderCode());
        if (providerInfoDO == null) {
            return CommonResult.error(PayResultCode.PROVIDER_NOT_EXITS);
        }
        PayChannelDO payChannelDO = payChannelService.queryByCode(merchantAccessReq.getChannelCode());
        if (payChannelDO == null) {
            return CommonResult.error(PayResultCode.PAY_CHANNEL_NOT_EXITS);
        }
        MerchantAccessDto merchantAccessDto = new MerchantAccessDto();

        OpenApiMerchantBusinessReq merchantAccessBusiness = merchantAccessReq.getMerchantAccessBusiness();
        // 进件主表信息
        MerchantAccessInfoDO merchantAccessInfoDO = new MerchantAccessInfoDO();
        merchantAccessInfoDO.setSn(localRequest.getSn());
        merchantAccessInfoDO.setProviderCode(merchantAccessReq.getProviderCode());
        merchantAccessInfoDO.setChannelCode(merchantAccessReq.getChannelCode());
        // merchantAccessInfoDO.setId(merchantAccessReq.getId());
        merchantAccessInfoDO.setControllerType(merchantAccessInfo.getControllerType());
        merchantAccessInfoDO.setContactType(merchantAccessInfo.getContactType());
        merchantAccessInfoDO.setType(merchantAccessInfo.getType());
        merchantAccessInfoDO.setRemark("");
        merchantAccessInfoDO.setMchOrderNo(merchantAccessReq.getMchOrderNo());
        merchantAccessInfoDO.setNotifyUrl(merchantAccessReq.getNotifyUrl());
        merchantAccessInfoDO.setMerchantAccessType(CommonEnum.YES_NO_TYPE.NO.getCode());
        merchantAccessInfoDO.setSourceFrom(MerchantEnum.SOURCE_FROM.OPEN_API.getCode());
        merchantAccessDto.setMerchantAccessInfo(merchantAccessInfoDO);
        merchantAccessInfoDO.setAppId(localRequest.getAppId());
        merchantAccessInfoDO.setSignType(localRequest.getSignType());
        // 进件营业执照信息
        OpenApiMerchantLicenseReq merchantAccessLicense = merchantAccessInfo.getMerchantAccessLicense();
        // 进件法人信息
        MerchantAccessCertInfoDO merchantAccessLegalDO = BeanUtil.copy(merchantAccessInfo.getMerchantAccessLegal(), MerchantAccessCertInfoDO.class);
        merchantAccessLegalDO.setOtherValue(merchantAccessInfo.getMerchantAccessLegal().getEmail());
        if (merchantAccessLicense != null) {
            MerchantAccessLicenseDO merchantAccessLicenseDO = BeanUtil.copy(merchantAccessLicense, MerchantAccessLicenseDO.class);
            merchantAccessDto.setMerchantAccessLicense(merchantAccessLicenseDO);
            merchantAccessInfoDO.setName(merchantAccessLicenseDO.getName());
        }
        else {
            merchantAccessInfoDO.setName(merchantAccessLegalDO.getName());
        }
        merchantAccessDto.setMerchantAccessLegal(merchantAccessLegalDO);

        // 联系人信息
        MerchantAccessCertInfoDO merchantAccessContactDO = BeanUtil.copy(merchantAccessInfo.getMerchantAccessContact(), MerchantAccessCertInfoDO.class);
        merchantAccessContactDO.setOtherValue(merchantAccessInfo.getMerchantAccessContact().getEmail());
        merchantAccessDto.setMerchantAccessContact(merchantAccessContactDO);

        // 实际控制人
        OpenApiMerchantCertReq merchantAccessController = merchantAccessInfo.getMerchantAccessController();
        if (merchantAccessController != null) {
            MerchantAccessCertInfoDO merchantAccessControllerDO = BeanUtil.copy(merchantAccessInfo.getMerchantAccessController(), MerchantAccessCertInfoDO.class);
            merchantAccessDto.setMerchantAccessController(merchantAccessControllerDO);
        }
        // 进件受益人信息
        List<OpenApiMerchantBenefitReq> merchantAccessBenefitList = merchantAccessInfo.getMerchantAccessBenefitList();
        if (!CollectionUtils.isEmpty(merchantAccessBenefitList)) {
            List<MerchantAccessCertInfoDO> merchantAccessBenefits = new ArrayList<>();
            merchantAccessBenefitList.stream().forEach(merchantAccessBenefitReq -> {
                MerchantAccessCertInfoDO merchantAccessCertInfoDO = BeanUtil.copy(merchantAccessBenefitReq, MerchantAccessCertInfoDO.class);
                merchantAccessCertInfoDO.setOtherValue(merchantAccessBenefitReq.getFinalBeneficiaryMode());
                merchantAccessBenefits.add(merchantAccessCertInfoDO);
            });
            merchantAccessDto.setMerchantAccessBenefitList(merchantAccessBenefits);
        }
        // 企业控股股东信息
        List<OpenApiMerchantCertReq> merchantAccessShareholderList = merchantAccessInfo.getMerchantAccessShareholderList();
        if (!CollectionUtils.isEmpty(merchantAccessBenefitList)) {
            List<MerchantAccessCertInfoDO> merchantAccessShareholders = BeanUtil.copy(merchantAccessShareholderList, MerchantAccessCertInfoDO.class);
            merchantAccessDto.setMerchantAccessShareholderList(merchantAccessShareholders);
        }
        // 经营信息
        MerchantAccessBusinessDO merchantAccessBusinessDO = BeanUtil.copy(merchantAccessBusiness, MerchantAccessBusinessDO.class);
        if (CollectionUtils.isNotEmpty(merchantAccessBusiness.getFileUrls())) {
            merchantAccessBusinessDO.setFileUrlJson(JsonUtils.toJsonString(merchantAccessBusiness.getFileUrls()));
        }
        if (CollectionUtils.isNotEmpty(merchantAccessBusiness.getBusinessLicenses())) {
            merchantAccessBusinessDO.setLicenseJson(JsonUtils.toJsonString(merchantAccessBusiness.getBusinessLicenses()));
        }

        // 进件场景信息
        List<MerchantAccessScene> merchantAccessSceneList = merchantAccessBusiness.getMerchantAccessSceneList();
        if (!CollectionUtils.isEmpty(merchantAccessSceneList)) {
            merchantAccessBusinessDO.setSceneJson(JsonUtils.toJsonString(merchantAccessSceneList));
        }
        // 进件结算卡信息
        MerchantAccessCardDO merchantAccessCardDO = BeanUtil.copy(merchantAccessReq.getMerchantAccessCard(), MerchantAccessCardDO.class);
        merchantAccessDto.setMerchantAccessBusiness(merchantAccessBusinessDO);
        merchantAccessDto.setMerchantAccessCard(merchantAccessCardDO);
        // if (!StringUtils.hasText(merchantAccessBusinessDO.getName())) {
        // merchantAccessBusinessDO.setName(merchantInfoDO.getName());
        // }
        merchantAccessInfoDO.setSnType(merchantInfoDO.getSnType());
        merchantAccessInfoDO.setSysType(localRequest.getSysType());
        if (merchantAccessInfo.getMerchantAccessType() != null && CommonEnum.YES_NO_TYPE.YES.getCode().equals(merchantAccessInfo.getMerchantAccessType())) {
            // 免审 直接发送 流程处理消息
            merchantAccessInfoDO.setStatus(MerchantEnum.ACCESS_STATUS.CHANNEL_WAIT_APPROVE.getCode());
            merchantAccessInfoDO.setMerchantAccessType(merchantAccessInfo.getMerchantAccessType());
        }
        else {
            merchantAccessInfoDO.setStatus(MerchantEnum.ACCESS_STATUS.SUBMIT.getCode());
        }
        merchantAccessInfoDO.setRemark("");
        if (accessInfoDO == null) {
            merchantAccessInfoDO = merchantAccessDto.getMerchantAccessInfo();
            merchantAccessInfoDO.setRequestId(IdUtils.getSnowflakeNextIdStr());
            merchantAccessInfoDO.setMerchantChannelId(IdUtils.getSnowflakeNextIdStr());
            merchantAccessService.saveAccess(merchantAccessDto);
        }
        else {
            merchantAccessInfoDO.setId(accessInfoDO.getId());
            // 恢复到上一个状态
            if (accessInfoDO.getLastStatus() != null && accessInfoDO.getLastStatus() > MerchantEnum.ACCESS_STATUS.CHANNEL_APPROVE.getCode()) {
                merchantAccessInfoDO.setStatus(accessInfoDO.getLastStatus());
            }
            merchantAccessService.updateAccess(merchantAccessDto);
        }
        return CommonResult.success(merchantAccessDto);
    }

    String key(String dictKey, String dictValue) {
        return dictValue + "_" + dictKey;
    }

    void sendMerchantAccessMessage(Long id) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        String jsonString = JsonUtils.toJsonString(map);
        log.info("sendMerchantAccessMessage:{}", jsonString);
        extRocketMQTemplate.send(MqConstant.MERCHANT_ACCESS_STATUS_TOPIC, jsonString);
    }

    @Override
    public CommonResult<MerchantAccessAuthResp> merchantAccessAuthPage(MerchantAccessAuthPageReq merchantAccessAuthPageReq) {

        // 分页返回集合
        MerchantAccessAuthResp merchantAccessAuthResp = new MerchantAccessAuthResp();
        // 之前逻辑走一遍 然后查分页
        CommonResult<MerchantAccessAuthResp> queryAccessAuthResp = queryMerchantAccessAuth(merchantAccessAuthPageReq.getId());
        MerchantAccessInfoDO merchantAccessInfo = null;
        // 认证集合
        if (queryAccessAuthResp.isSuccess() && queryAccessAuthResp.getData() != null) {
            merchantAccessAuthResp.setMerchantAcctBalanceDto(queryAccessAuthResp.getData().getMerchantAcctBalanceDto());
            merchantAccessAuthResp.setWechatConfig(queryAccessAuthResp.getData().getWechatConfig());
            merchantAccessInfo = queryAccessAuthResp.getData().getMerchantAccessInfo();
        }
        // 分页查询AUT信息
        MerchantAccessAuthQueryDto merchantAccessAuthQueryDto = BeanUtil.copyProperties(merchantAccessAuthPageReq, MerchantAccessAuthQueryDto.class);
        merchantAccessAuthQueryDto.setAccessId(merchantAccessAuthPageReq.getId());
        processQueryDate(merchantAccessAuthPageReq, merchantAccessAuthQueryDto);
        PageResult<MerchantAccessAuthDO> pageResult = merchantAccessAuthService.queryAuthPage(merchantAccessAuthQueryDto);

        // 列表返回显示AuthUrl
        if(CollUtil.isNotEmpty(pageResult.getList()) && merchantAccessInfo != null){
            ProviderChannelConfigDO providerChannelConfigDO = providerService.queryConfig(merchantAccessInfo.getProviderCode(), merchantAccessInfo.getChannelCode());
            String paramsConfig = providerChannelConfigDO.getParamsConfig();
            Map<String, Object> paramsMap = JsonUtils.parseObject(paramsConfig, Map.class);
            for(MerchantAccessAuthDO accessAuth: pageResult.getList()){
                if (!StringUtils.hasText(accessAuth.getAuthUrl())) {
                    PayEnums.PAY_TYPE payType = PayEnums.PAY_TYPE.fromByCode(accessAuth.getType());
                    if (!StringUtils.hasText(accessAuth.getAuthUrl())) {
                        switch (payType) {
                            case WECHAT:
                                Object object = paramsMap.get("wxQrcode");
                                if (object != null) {
                                    accessAuth.setAuthUrl(object.toString());
                                }
                                break;
                            case ALIPAY:
                                object = paramsMap.get("aliQrcode");
                                if (object != null) {
                                    accessAuth.setAuthUrl(object.toString());
                                }
                                break;
                        }
                    }
                }
           }
        }

        PageResult<MerchantAccessAuthDetailResp> pageAuthResps = buildAccessAuthPageResult(pageResult, pageResult.getList());
        merchantAccessAuthResp.setAuthPage(pageAuthResps);

        MerchantAppQueryDto merchantAppQueryDto = new MerchantAppQueryDto();
        merchantAppQueryDto.setAccessId(merchantAccessAuthPageReq.getId());
        merchantAppQueryDto.setAccessType(MerchantEnum.DATA_RELATION_TYPE.ACCESS.getCode());
        MerchantAppChannelDO merchantAppChannel = merchantApplicationService.queryDetailByAccessId(merchantAccessAuthPageReq.getId(), MerchantEnum.DATA_RELATION_TYPE.ACCESS);
        if (merchantAppChannel!=null) {
            merchantAccessAuthResp.setMchChannelCode(merchantAppChannel.getCode());
        }


        return CommonResult.success(merchantAccessAuthResp);
    }

    @Override
    public CommonResult<PageResult<MerchantAccessAuthDetailResp>> merchantAccessSnAuthPage(MerchantAccessSnAuthPageReq merchantAccessAuthPageReq) {
        // 分页查询AUT信息
        MerchantAccessAuthQueryDto merchantAccessAuthQueryDto = BeanUtil.copyProperties(merchantAccessAuthPageReq, MerchantAccessAuthQueryDto.class);
        processQueryDate(merchantAccessAuthPageReq, merchantAccessAuthQueryDto);
        List<String> accessIdList = new ArrayList<>();
        // 通道查询商户
        if(StrUtil.isNotEmpty(merchantAccessAuthPageReq.getChannelCode())){
            MerchantAccessInfoPageQueryDto merchantAccessInfoPageQueryDto = new MerchantAccessInfoPageQueryDto();
            merchantAccessInfoPageQueryDto.setChannelCode(merchantAccessAuthPageReq.getChannelCode());
            List<MerchantAccessInfoDO> merchantAccessInfoDOList = merchantAccessService.queryList(merchantAccessInfoPageQueryDto);
            for(MerchantAccessInfoDO merchantAccessInfoDO:merchantAccessInfoDOList){
                accessIdList.add(merchantAccessInfoDO.getId().toString());
            }
        }
        // 去重
        if(CollUtil.isNotEmpty(accessIdList)){
            accessIdList = accessIdList.stream().distinct().collect(Collectors.toList());
            merchantAccessAuthQueryDto.setAccessIdList(accessIdList);
        }
        PageResult<MerchantAccessAuthDO> pageResult = merchantAccessAuthService.queryAuthPage(merchantAccessAuthQueryDto);
        // 列表返回显示AuthUrl
        if(CollUtil.isNotEmpty(pageResult.getList())){
            for(MerchantAccessAuthDO accessAuth: pageResult.getList()){
                if (!StringUtils.hasText(accessAuth.getAuthUrl())) {
                    MerchantAccessInfoDO merchantAccessInfo = merchantAccessService.detail(accessAuth.getAccessId());
                    if (merchantAccessInfo == null) continue;
                    ProviderChannelConfigDO providerChannelConfigDO = providerService.queryConfig(merchantAccessInfo.getProviderCode(), merchantAccessInfo.getChannelCode());
                    String paramsConfig = providerChannelConfigDO.getParamsConfig();
                    Map<String, Object> paramsMap = JsonUtils.parseObject(paramsConfig, Map.class);
                    PayEnums.PAY_TYPE payType = PayEnums.PAY_TYPE.fromByCode(accessAuth.getType());
                    if (!StringUtils.hasText(accessAuth.getAuthUrl())) {
                        switch (payType) {
                            case WECHAT:
                                Object object = paramsMap.get("wxQrcode");
                                if (object != null) {
                                    accessAuth.setAuthUrl(object.toString());
                                }
                                break;
                            case ALIPAY:
                                object = paramsMap.get("aliQrcode");
                                if (object != null) {
                                    accessAuth.setAuthUrl(object.toString());
                                }
                                break;
                        }
                    }
                }
            }
        }
        PageResult<MerchantAccessAuthDetailResp> pageAuthResps = buildAccessAuthPageResult(pageResult, pageResult.getList());
        return CommonResult.success(pageAuthResps);
    }

    @Override
    public CommonResult<Void> updateAccessAuthState(UpdateMerchantAccessAuthStateReq updateAccessAuthStateReq) {
        log.info("updateAccessAuthState updateAccessAuthStateReq:{}", JsonUtils.toJsonString(updateAccessAuthStateReq));
        try {
            MerchantAccessAuthDO merchantAccessAuthDO = merchantAccessAuthService.queryMerchantAccessAuthById(updateAccessAuthStateReq.getId());
            if (merchantAccessAuthDO == null) {
                return CommonResult.error(CommonResultCode.DATA_NOT_EXIST);
            }
            MerchantAccessAuthDO updateMerchantAccessAuthDO = new MerchantAccessAuthDO();
            updateMerchantAccessAuthDO.setState(updateAccessAuthStateReq.getState());
            updateMerchantAccessAuthDO.setId(updateAccessAuthStateReq.getId());
            merchantAccessAuthService.updateMerchantAccessAuthList(CollUtil.newArrayList(updateMerchantAccessAuthDO));

            // businessLogService.addBusinessChangeLog(merchantAccessAuthDO.getSn(),
            // CommonEnum.CHANGE_LOG_TYPE.MESSAGE_TEMPLATE.getCode(),
            // CommonEnum.CHANGE_LOG_MODEL_TYPE.COMMON, merchantAccessAuthDO,
            // updateMerchantAccessAuthDO);

            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("updateMerchantInfo error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> updateAccessAuth(MerchantAccessAuthDO merchantAccessAuthDO) {
        if(merchantAccessAuthDO.getId() != null){
            merchantAccessAuthService.updateMerchantAccessAuth(merchantAccessAuthDO);
        }
        return CommonResult.success();
    }

    @Override
    public CommonResult<Void> updateAccessAuthLimitRouter(UpdateMerchantAccessAuthStateReq updateAccessAuthStateReq) {
        log.info("updateAccessAuthLimitRouter updateAccessAuthStateReq:{}", JsonUtils.toJsonString(updateAccessAuthStateReq));
        try {
            MerchantAccessAuthDO merchantAccessAuthDO = merchantAccessAuthService.queryMerchantAccessAuthById(updateAccessAuthStateReq.getId());
            if (merchantAccessAuthDO == null) {
                return CommonResult.error(CommonResultCode.DATA_NOT_EXIST);
            }
            MerchantAccessAuthDO updateMerchantAccessAuthDO = new MerchantAccessAuthDO();
            updateMerchantAccessAuthDO.setLimitRouter(updateAccessAuthStateReq.getState());
            updateMerchantAccessAuthDO.setId(updateAccessAuthStateReq.getId());
            merchantAccessAuthService.updateMerchantAccessAuth(updateMerchantAccessAuthDO);

            // businessLogService.addBusinessChangeLog(merchantAccessAuthDO.getSn(),
            // CommonEnum.CHANGE_LOG_TYPE.MESSAGE_TEMPLATE.getCode(),
            // CommonEnum.CHANGE_LOG_MODEL_TYPE.COMMON, merchantAccessAuthDO,
            // updateMerchantAccessAuthDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("updateMerchantInfo error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> delAuth(Long id) {
        log.info("delAuth id:{}", id);
        try {
            merchantAccessAuthService.delAuth(id);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("delAuth error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<MerchantProductReq> updateProduct(MerchantProductReq merchantProductReq) {
        MerchantAppChannelDO merchantAppChannelDO = merchantApplicationService.queryAppChannelDetail(merchantProductReq.getMchChannelCode());
        if (merchantAppChannelDO == null || merchantProductReq == null) {
            return CommonResult.error(MerchantResultCode.MERCHANT_APP_NOT_EXIST);
        }
        MerchantAccessDto merchantAccessDto = merchantAccessService.domainDetail(merchantAppChannelDO.getAccessId());
        CommonResult<Void> commonResult = merchantAccessGateway.productUpdate(merchantAccessDto, merchantAppChannelDO, merchantProductReq);
        if(!commonResult.isSuccess()) {
            return CommonResult.error(OpenApiResultCode.MERCHANT_CHANNEL_SPLIT_ERROR.getCode(), commonResult.getMsg());
        }
        return CommonResult.success(merchantProductReq);
    }

    @Override
    public CommonResult<MerchantProductQueryResp> queryProduct(MerchantProductReq merchantProductReq) {
        MerchantAppChannelDO merchantAppChannelDO = merchantApplicationService.queryAppChannelDetail(merchantProductReq.getMchChannelCode());
        if (merchantAppChannelDO == null || merchantProductReq == null) {
            return CommonResult.error(MerchantResultCode.MERCHANT_APP_NOT_EXIST);
        }
        MerchantAccessDto merchantAccessDto = merchantAccessService.domainDetail(merchantAppChannelDO.getAccessId());
        CommonResult<MerchantProductQueryResp> commonResult = merchantAccessGateway.productQuery(merchantAccessDto, merchantAppChannelDO, merchantProductReq);
        if(!commonResult.isSuccess()) {
            return CommonResult.error(OpenApiResultCode.MERCHANT_CHANNEL_SPLIT_ERROR.getCode(), commonResult.getMsg());
        }
        return CommonResult.success(commonResult.getData());
    }

    @Override
    public String randomMchId(String subMchId, PayEnums.PAY_TYPE payType) {

        // 通过子商户号获取进件信息
        MerchantAccessInfoDO merchantAccessInfoDO = merchantAccessService.queryBySubMchId(subMchId);
        if(merchantAccessInfoDO == null){
            return null;
        }
        // 进件ID
        Long accessId = merchantAccessInfoDO.getId();
        if(accessId == null || payType == null){
            return null;
        }
        List<MerchantAccessAuthDO> authDOList = merchantAccessAuthService.queryMerchantAccessAuth(accessId, payType);
        if(CollUtil.isNotEmpty(authDOList)){
            // 权重对象
            List<WeightRandom.WeightObj<String>> weightList = new ArrayList<>();
            for(MerchantAccessAuthDO authDO:authDOList){
                // 状态开启-是否轮询开启
                if(authDO.getState() != null && authDO.getState() == 1 &&
                        authDO.getLimitRouter() != null && authDO.getLimitRouter() == 1){
                    weightList.add(new WeightRandom.WeightObj<>(authDO.getSerialCode(),authDO.getWeight()));
                }
            }
            // 没有设置轮询 只获取第一个
            if(CollUtil.isEmpty(weightList)){
                return authDOList.get(0).getSubMchId();
            }
            // 随机权重
            WeightRandom<String> wr = RandomUtil.weightRandom(weightList);
            if(wr == null){
                authDOList.get(0).getSubMchId();
            }
            return wr.next();
        }
        return null;
    }

    @Override
    public MerchantAccessAuthDO randomMchIdByChannelCode(String channelCode, PayEnums.PAY_TYPE payType) {

        MerchantAppChannelDO appChannelDO = merchantApplicationService.queryAppChannelDetail(channelCode);
        if(appChannelDO == null){
            return null;
        }
        // 进件ID
        Long accessId = appChannelDO.getAccessId();
        if(accessId == null || payType == null){
            return null;
        }
        List<MerchantAccessAuthDO> authDOList = merchantAccessAuthService.queryMerchantAccessAuth(accessId, payType);
        if(CollUtil.isNotEmpty(authDOList)){
            // 权重对象
            List<WeightRandom.WeightObj<MerchantAccessAuthDO>> weightList = new ArrayList<>();
            for(MerchantAccessAuthDO authDO:authDOList){
                // 不判断轮训状态，强制开启轮训
                if(authDO.getState() != null && authDO.getState() == 1){
                    weightList.add(new WeightRandom.WeightObj<>(authDO,authDO.getWeight()));
                }
            }
            // 没有设置轮询 只获取第一个
            if(CollUtil.isEmpty(weightList)){
                return authDOList.get(0);
            }
            // 随机权重
            WeightRandom<MerchantAccessAuthDO> wr = RandomUtil.weightRandom(weightList);
            if(wr == null){
                return authDOList.get(0);
            }
            return wr.next();
        }
        return null;
    }

    public PageResult<MerchantAccessAuthDetailResp> buildAccessAuthPageResult(PageResult pageResult, List<MerchantAccessAuthDO> list) {
        PageResult<MerchantAccessAuthDetailResp> result = new PageResult<>();
        result.setPageNo(pageResult.getPageNo());
        result.setPageSize(pageResult.getPageSize());
        result.setPages(pageResult.getPages());
        result.setTotal(pageResult.getTotal());
        if (CollUtil.isEmpty(list)) {
            result.setList(CollUtil.newArrayList());
        }
        else {
            List<MerchantAccessAuthDetailResp> resps = new ArrayList<>();
            MerchantAccessAuthDetailResp resp = new MerchantAccessAuthDetailResp();
            for (MerchantAccessAuthDO merchantAccessAuthDO : list) {
                resp = BeanUtil.copyProperties(merchantAccessAuthDO, MerchantAccessAuthDetailResp.class);
                MerchantAccessInfoDO merchantAccessInfoDO = merchantAccessService.detail(merchantAccessAuthDO.getAccessId());
                if(merchantAccessInfoDO != null){
                    resp.setChannelCode(merchantAccessInfoDO.getChannelCode());
                    PayChannelDO payChannelDO = payChannelService.queryByCode(merchantAccessInfoDO.getChannelCode());
                    if(payChannelDO != null){
                        resp.setChannelName(payChannelDO.getName());
                    }
                }
                if(StrUtil.isNotEmpty(merchantAccessAuthDO.getSn())){
                    MerchantInfoDO merchantInfoDO = merchantService.queryMerchant(merchantAccessAuthDO.getSn());
                    if(merchantInfoDO != null){
                        resp.setMerchantName(merchantInfoDO.getName());
                    }
                }
                resps.add(resp);
            }
            result.setList(resps);
        }
        return result;
    }

    public String getPayWaycodes(String sn, String channelCode) {
        MerchantConfigDO merchantConfigDO = merchantInfoAppService.queryConfig(sn);
        if (merchantConfigDO != null) {
            if (StringUtils.hasText(merchantConfigDO.getFeeConfig())) {
                List<MerchantFeeConfigResp> providerChannelFeeConfigList = JsonUtils.parseArray(merchantConfigDO.getFeeConfig(), MerchantFeeConfigResp.class);
                List<String> payWayCodes = providerChannelFeeConfigList.stream()
                        .filter(merchantFeeConfigResp -> CommonEnum.YES_NO_TYPE.YES.getCode().equals(merchantFeeConfigResp.getStatus()))
                        .map(merchantFeeConfigResp -> merchantFeeConfigResp.getPayWayCode()).collect(Collectors.toList());
                if (StringUtils.hasText(channelCode)) {
                    PayChannelDO payChannelDO = payChannelService.queryByCode(channelCode);
                    if (!CollectionUtils.isEmpty(payChannelDO.getPayWapCodeList())) {
                        Collection<String> intersection = CollectionUtils.intersection(payWayCodes, payChannelDO.getPayWapCodeList());
                        if (CollectionUtils.isEmpty(intersection)) {
                            return "";
                        }
                        payWayCodes = new ArrayList<>(intersection);
                    }
                }

                return JsonUtils.toJsonString(payWayCodes);
            }
            else {
                return "";
            }
        }
        else {
            return "";
        }
    }

    public static void main(String[] args) {
        List<WeightRandom.WeightObj<MerchantAccessAuthDO>> weightList = new ArrayList<>();

        MerchantAccessAuthDO authDO1 = new MerchantAccessAuthDO();
        authDO1.setWeight(1);
        authDO1.setMchId("1111");
        weightList.add(new WeightRandom.WeightObj<>(authDO1,authDO1.getWeight()));

        MerchantAccessAuthDO authDO2 = new MerchantAccessAuthDO();
        authDO2.setWeight(1);
        authDO2.setMchId("2222");
        weightList.add(new WeightRandom.WeightObj<>(authDO2,authDO2.getWeight()));

        MerchantAccessAuthDO authDO3 = new MerchantAccessAuthDO();
        authDO3.setWeight(1);
        authDO3.setMchId("3333");
        weightList.add(new WeightRandom.WeightObj<>(authDO3,authDO3.getWeight()));

        WeightRandom<MerchantAccessAuthDO> wr = RandomUtil.weightRandom(weightList);
        System.out.println(wr.next().getMchId());
    }
}
